<template>
	<section class="table-demo-container">
		<section class="table-demo-padding layout-padding-view layout-padding-auto">
			<el-card class="mb10" shadow="hover" v-show="state.searchVisible">
				<div class="table-search-container mt10 pl10 pr10">
					<el-form v-if="state.searchForm" ref="tableSearchRef" :model="state.searchForm" label-width="100px" class="table-form">
						<el-row>
							<el-col
								:xs="24"
								:sm="12"
								:md="8"
								:lg="8"
								:xl="6"
								class="mb20"
								v-for="(val, key) in getSearchData"
								:key="key"
								v-show="key === 0 || state.isToggle"
							>
								<template v-if="val.type !== ''">
									<el-form-item
										:label="val.label"
										:prop="val.prop"
										:rules="[{ required: val.required, message: `${val.label}不能为空`, trigger: val.type === 'input' ? 'blur' : 'change' }]"
									>
										<el-input
											v-model="state.searchForm[val.prop]"
											:placeholder="val.placeholder"
											clearable
											v-if="val.type === 'input'"
											style="width: 100%"
										/>
										<el-date-picker
											v-model="state.searchForm[val.prop]"
											type="date"
											:placeholder="val.placeholder"
											v-else-if="val.type === 'date'"
											style="width: 100%"
											format="YYYY-MM-DD"
											value-format="YYYY-MM-DD"
										/>
										<el-select
											v-model="state.searchForm[val.prop]"
											:placeholder="val.placeholder"
											v-else-if="val.type === 'select'"
											style="width: 100%"
										>
											<el-option v-for="item in val.options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
										</el-select>
									</el-form-item>
								</template>
							</el-col>
							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="12" class="mb20">
								<el-form-item class="table-form-btn">
									<template #label v-if="state.searchForm">
										<div class="table-form-btn-toggle ml10" @click="state.isToggle = !state.isToggle">
											<span>{{ state.isToggle ? '收起功能栏' : '展开功能栏' }}</span>
											<SvgIcon :name="state.isToggle ? 'ele-ArrowUp' : 'ele-ArrowDown'" />
										</div>
									</template>
									<div>
										<template v-if="!getSearchConfig?.isHide">
											<el-button type="primary" icon="Search" @click="onSearch()">查询 </el-button>
											<el-button type="info" class="ml10" icon="RefreshLeft" @click="initFormField(true)"> 重置 </el-button>
										</template>
									</div>
								</el-form-item>
							</el-col>
						</el-row>
					</el-form>
				</div>
			</el-card>
			<el-card>
				<template #header>
					<div class="card-header">
						<span>{{ getConfig?.name }}</span>
						<section class="quick_operate">
							<slot name="search"></slot>

							<slot name="selection" :row="state.selectlist"></slot>

							<el-tooltip
								v-if="!getSearchConfig.isHide"
								class="box-item"
								effect="dark"
								:content="state.searchVisible ? '隐藏搜索' : '打开搜索'"
								placement="top"
							>
								<el-button
									:icon="state.searchVisible ? 'Hide' : 'Search'"
									circle
									:type="state.searchVisible ? 'warning' : 'primary'"
									@click="showSearchVisible"
								/>
							</el-tooltip>
							<el-tooltip v-if="getConfig.isImport" class="box-item" effect="dark" content="导入表格" placement="top">
								<el-button icon="Upload" circle type="success" @click="onImportTable" />
							</el-tooltip>
							<el-popconfirm
								v-if="getConfig.isExport"
								width="220"
								confirm-button-text="导出全部数据"
								cancel-button-text="导出当前页"
								icon="InfoFilled"
								icon-color="#626AEF"
								title="请选择导出类型?"
								@confirm="onExportTable(0)"
								@cancel="onExportTable(1)"
							>
								<template #reference> <el-button icon="Refresh" circle type="success" /> </template>
							</el-popconfirm>
							<el-tooltip class="box-item" v-if="getConfig.isAdd" effect="dark" content="新增" placement="top">
								<el-button icon="Plus" circle type="primary" @click="onAppendTable" />
							</el-tooltip>
							<el-tooltip class="box-item" effect="dark" content="刷新表格" placement="top">
								<el-button icon="Refresh" circle type="primary" @click="initComponent" />
							</el-tooltip>

							<el-popover
								placement="top-end"
								trigger="click"
								transition="el-zoom-in-top"
								popper-class="table-tool-popper"
								:width="300"
								:persistent="false"
								@show="onSetTable"
							>
								<template #reference>
									<el-button icon="Setting" circle type="primary" />
								</template>
								<template #default>
									<div class="tool-box">
										<el-tooltip content="拖动进行排序" placement="top-start">
											<SvgIcon name="fa fa-question-circle-o" :size="17" class="ml11" color="#909399" />
										</el-tooltip>
										<el-checkbox
											v-model="state.checkListAll"
											:indeterminate="state.checkListIndeterminate"
											class="ml10 mr1"
											label="列显示"
											@change="onCheckAllChange"
										/>
										<el-checkbox v-model="getConfig.isSerialNo" class="ml12 mr1" label="序号" />
										<el-checkbox v-model="getConfig.isSelection" class="ml12 mr1" label="多选" v-if="getConfig.isSelection" />
									</div>
									<el-scrollbar>
										<div ref="toolSetRef" class="tool-sortable">
											<div class="tool-sortable-item" v-for="v in setHeader" :key="v.key" :data-key="v.key">
												<i class="fa fa-arrows-alt handle cursor-pointer"></i>
												<el-checkbox v-model="v.isCheck" size="default" class="ml12 mr8" :label="v.title" @change="onCheckChange" />
											</div>
										</div>
									</el-scrollbar>
								</template>
							</el-popover>
						</section>
					</div>
				</template>
				<div class="table-container">
					<el-table
						ref="tableMainRef"
						:data="state.tableOption.dataPool"
						:border="getConfig.isBorder"
						v-bind="$attrs"
						stripe
						:height="height"
						:row-key="getConfig.rowKey || 'id'"
						style="width: 100%"
						v-loading="state.tableOption.loading"
						@selection-change="onSelectionChange"
						:tree-props="getConfig.treeProps"
					>
						<el-table-column fixed="left" type="selection" align="center" :reserve-selection="true" width="50" v-if="getConfig.isSelection" />
						<el-table-column fixed="left" type="index" label="序号" align="center" width="80" v-if="getConfig.isSerialNo" />
						<el-table-column
							v-for="(item, index) in setHeader"
							:key="index"
							show-overflow-tooltip
							align="center"
							:prop="item.key"
							:width="item.colWidth"
							:label="item.title"
						>
							<template v-slot="scope">
								<template v-if="item.type === 'image'">
									<el-image
										:src="scope.row[item.key]"
										style="width: 55px; height: 55px"
										:preview-src-list="[scope.row[item.key]]"
										fit="cover"
										preview-teleported
										v-if="scope.row[item.key]"
									/>
								</template>
								<template v-else-if="item.type === 'switch'">
									<el-switch
										v-model="scope.row[item.key]"
										:active-value="item.active"
										:inactive-value="item.inactive"
										:active-text="item.activeText || '启用'"
										:inactive-text="item.inactiveText || '禁用'"
										@change="columSwitch(scope.row, item)"
									/>
								</template>
								<template v-else-if="item.type === 'tag'">
									<el-tag :type="item.options[scope.row[item.key]].type">{{ item.options[scope.row[item.key]].label }}</el-tag>
								</template>
								<template v-else-if="item.type === 'format'">
									{{ item.options[scope.row[item.key]].label }}
								</template>
								<template v-else>
									{{ scope.row[item.key] ? scope.row[item.key] : '暂无数据' }}
								</template>
							</template>
						</el-table-column>
						<el-table-column label="操作" :min-width="150" :width="getConfig.operateWidth" align="center" fixed="right" v-if="getConfig.isOperate">
							<template v-slot="scope">
								<slot :row="scope.row" name="handle" />
							</template>
						</el-table-column>
						<template #empty>
							<el-empty description="暂无数据" />
						</template>
					</el-table>
					<div class="table-footer mt15">
						<el-pagination
							v-model:current-page="state.tableOption.params.pageIndex"
							v-model:page-size="state.tableOption.params.pageSize"
							:pager-count="5"
							:page-sizes="[20, 50, 100, 200, 500, 1000]"
							:total="state.tableOption.total"
							layout="total, sizes, prev, pager, next, jumper"
							background
							@size-change="onHandleSizeChange"
							@current-change="onHandleCurrentChange"
						>
						</el-pagination>
					</div>
				</div>
			</el-card>
		</section>
		<ImportTable ref="importTableRef"></ImportTable>
	</section>
</template>

<script setup lang="ts" name="AmxxTable">
import { reactive, computed, nextTick, ref, onMounted, watchEffect, watch, defineAsyncComponent, inject } from 'vue';
import { ElMessage, ElNotification } from 'element-plus';
import table2excel from 'js-table2excel';
import Sortable, { clone } from 'sortablejs';
import { storeToRefs } from 'pinia';
// import { useThemeConfig } from '/@/stores/themeConfig';
import '/@/theme/tableTool.scss';
import {allApiType} from '/@/api/api'
// import { deepCopy, initRow } from '/@/utils/tools';

const ImportTable = defineAsyncComponent(() => import('./importTable.vue'));

// const allApiType: any = inject('$request');

const tools: any = inject('$tools');

const emit = defineEmits(['onAppendTable']);

// 定义父组件传过来的值
const props = defineProps({
	options: {
		type: Object,
		default: () => {},
	},
	height: {
		type: [Number, String],
		default: () => 680,
	},
});
// 定义变量内容
const tableMainRef = ref();
const toolSetRef = ref();
const importTableRef = ref();
// const storesThemeConfig = useThemeConfig();
// const { themeConfig } = storeToRefs(storesThemeConfig);
const state = reactive<any>({
	searchForm: null,
	searchVisible: false,
	isToggle: false, //是否收起搜索栏
	selectlist: [],
	checkListAll: true, //
	checkListIndeterminate: false, //表格全选中间状态
	tableOption: {
		header: [],
		dataPool: [],
		total: '',
		loading: false,
		params: {
			pageIndex: 1,
			pageSize: 20,
		},
	},
});
// 设置边框显示/隐藏
const setBorder = computed(() => {
	return props.options.isBorder ? true : false;
});
// 获取父组件 配置项（必传）
const getConfig = computed(() => {
	return props.options.config;
});
// 设置 tool header 数据
const setHeader = computed(() => {
	return state.tableOption.header.filter((v: any) => v.isCheck);
});
const getParams = computed(() => {
	return props.options.source.params;
});
const getSearchConfig = computed(() => {
	return props.options.SearchOptions;
});
const getSearchData = computed(() => {
	return props.options.search;
});
function onAppendTable() {
	emit('onAppendTable');
}

function onSelectionChange(selection: any) {
	state.selectlist = selection;
}
function showSearchVisible() {
	state.searchVisible = !state.searchVisible;
	if (state.searchVisible) {
		ElNotification.closeAll(); //关闭所有搜索提示
	} else {
		let msgHtml = '';
		getSearchData.value.map((item: any) => {
			if (state.searchForm[item.prop]) {
				msgHtml += `<p><strong>${item.label}:${state.searchForm[item.prop] || '<暂未设置条件>'}</strong></p>`;
			}
		});
		if (msgHtml) {
			ElNotification({
				title: '当前搜索的条件',
				dangerouslyUseHTMLString: true,
				message: msgHtml,
				showClose: true,
				duration: 0,
				icon: 'Search',
				position: 'bottom-right',
			});
		}
	}
}
function onSearch() {
	state.tableOption.params.pageIndex = 1;
	state.tableOption.params = state.searchForm;
	initComponent();
}
async function columSwitch(row: any, colum: any) {
	let params = {};
	colum.callback.params.forEach((key: any) => {
		params[key] = row[key];
	});
	if (colum.callback) {
		await allApiType(colum.callback.url, colum.callback.method, params);
		ElMessage.success('操作成功');
	} else {
		ElMessage.error('请配置Switch的Callback配置');
	}
}
// tool 列显示全选改变时
function onCheckAllChange<T>(val: T) {
	if (val) setHeader.value.forEach((v: any) => (v.isCheck = true));
	else setHeader.value.forEach((v: any) => (v.isCheck = false));
	state.checkListIndeterminate = false;
}
// tool 列显示当前项改变时
function onCheckChange() {
	const headers = setHeader.value.filter((v: any) => v.isCheck).length;
	state.checkListAll = headers === setHeader.value.length;
	state.checkListIndeterminate = headers > 0 && headers < setHeader.value.length;
}

//初始化表格设置
function onSetTable() {
	nextTick(() => {
		const sortable = Sortable.create(toolSetRef.value, {
			handle: '.handle',
			dataIdAttr: 'data-key',
			animation: 150,
			onEnd: () => {
				const headerList: EmptyObjectType[] = [];
				sortable.toArray().forEach((val) => {
					state.tableOption.header.forEach((v: any) => {
						if (v.key === val) headerList.push({ ...v });
					});
				});
				state.tableOption.header = headerList;
			},
		});
	});
}
//导入数据
function onImportTable() {
	importTableRef.value.initComponent(setHeader, getConfig.value.importOptios);
}
//导出数据
async function onExportTable(val: number) {
	if (val === 0) {
		//导出全部数据
		state.tableOption.params.pageIndex = 1;
		state.tableOption.params.pageSize = state.tableOption.total;
		await initComponent();
		importTableRef.value.ExportTable(state.tableOption.dataPool, setHeader.value, getConfig.value.name);
	} else {
		if (state.selectlist && state.selectlist.length > 0) {
			//导出选中数据
			importTableRef.value.ExportTable(state.tableOption.dataPool, setHeader.value, getConfig.value.name);
		} else {
			//导出当前页
			importTableRef.value.ExportTable(state.tableOption.dataPool, setHeader.value, getConfig.value.name);
		}
	}
}
//组件初始化数据
function initComponent() {
	return new Promise<void>((resolve, reject) => {
		if (state.tableOption.params.startTime !== '' && state.tableOption.params.startTime && !state.tableOption.params.endTime) {
			ElMessage.warning('请选择结束时间');
		} else if (state.tableOption.params.endTime !== '' && state.tableOption.params.endTime && !state.tableOption.params.startTime) {
			ElMessage.warning('请选择开始时间');
		} else {
			state.tableOption.loading = true;
			tableMainRef.value.clearSelection();
			allApiType(props.options.source.url, props.options.source.method, state.tableOption.params)
				.then((table: tablePage) => {
					state.tableOption.loading = false;
					state.tableOption.dataPool = table.data?.list ?? table.data;
					state.tableOption.total = table.data.total ?? state.tableOption.dataPool.length;
					resolve();
				})
				.catch((err: any) => {
					state.tableOption.loading = false;
					console.error(err, '模拟数据');
					reject();
				});
		}
	});
}
//pageIndex 改变
function onHandleCurrentChange(val: number) {
	state.tableOption.params.pageIndex = val;
	initComponent();
}
// pageSize 改变
function onHandleSizeChange(val: number) {
	state.tableOption.params.pageIndex = 1;
	state.tableOption.params.pageSize = val;
	initComponent();
}

function initFormField(callback?: boolean) {
	if (getSearchData.value.length <= 0) return false;
	let params = {};
	getSearchData.value.forEach((v: any) => (params[v.prop] = ''));
	state.searchForm = params;
	state.tableOption.params = tools.deepMerge(state.searchForm, props.options.source.params);
	state.searchForm = tools.deepMerge(state.searchForm, state.tableOption.params);
	let searchTask: any = [];
	let searchConfig = tools.deepCopy(getSearchData.value);
	searchConfig.forEach((search: any) => {
		if (search.remote) {
			searchTask.push(
				new Promise<void>((resolve, reject) => {
					tools
						.allApiType({
							url: search.remote.url,
							method: 'GET',
						})
						.then((remoteResult: result) => {
							switch (search.type) {
								case 'select':
									let dataPool = remoteResult.data?.list || remoteResult.data;
									search.options = dataPool.map((item: any) => {
										return {
											label: item[search.remote.props.label],
											value: item[search.remote.props.value],
										};
									});
									resolve();
									break;
							}
						});
				})
			);
		}
	});
	Promise.all(searchTask).then(() => {
		state.searchConfig = searchConfig;
	});
	if (callback) {
		initComponent();
	}
}
watch(
	() => props.options,
	() => {
		if (props.options.source.params) {
			state.tableOption.params = tools.initRow(state.tableOption.params, props.options.source.params);
		}
		state.tableOption.header = props.options.header;
		nextTick(() => {
			initFormField();
			initComponent();
		});
	},
	{ immediate: true, deep: true }
);
// 暴露变量
defineExpose({
	tableMainRef,
	toolSetRef,
	initComponent,
	initFormField,
});
</script>

<style lang="scss">
::v-deep .el-card__body {
	padding: unset;
	border: unset;
}
::v-deep .cell {
	width: max-content;
	// display: inline-block !important;
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: space-between;
}

.table-demo-container {
	.table-demo-padding {
		padding: 15px;
		.table-demo {
			flex: 1;
			overflow: hidden;
		}
	}
	.table-footer {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 0 24px 12px 24px;
	}
}
.table-search-container {
	display: flex;
	.table-form {
		flex: 1;
		.table-form-btn-toggle {
			white-space: nowrap;
			user-select: none;
			display: flex;
			align-items: center;
			color: var(--el-color-primary);
		}
	}
}
.card-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	.quick_operate {
		display: flex;
		align-items: center;
	}
}
</style>
